<?php 

class Event_CallCenterPreValidation extends Crud_Event_Handler 
{
	protected $_type = 'preValidation';
	
	/**
	 * Run handler with options array.
	 * 
	 * @param OrdersRow $row
	 * @return void
	 */
	public function run($row)
	{
		if ($row instanceof Crud_Section_Row) {
			$row = $row->getRow();
		}
	
		$service = OrderStatusPeer::getInstance();
		$placed = $service->getStatusByKey(OrdersService::STATUS_ORDER_PLACED);
		
		if ($this->_getParam('exit')) {
			$this->_exit($row);
		}else if ($this->_getParam('cancel') && !$row->isCanceled()) {
			$row->addLog("%s отменил заказ");
			$this->_cancel($row);
		}else if($this->_getParam('canceled_copy') && !$row->isCanceledCopy()){
			$row->addLog("%s отменил заказ содержащий копию");
		}else if ($this->_getParam('uncall') && $this->_getParam('action') == 'edit' && $row->getOrderStatusId() == $placed->getId()) {			
			$this->_uncall($row);		
		}
	}
	
	/**
	 * Just close lock and exit from order.
	 * 
	 * @param OrdersRow $row
	 * @return void
	 */
	protected function _exit($row)
	{
		if ($this->_getParam('action') == 'edit') {
			$section = AdminSectionPeer::getInstance()->fetchByKey($this->_getParam('table'));
			$select = AdminLockPeer::getInstance()->select();
			$select->where(AdminLockPeer::SECTION_ID, $section->getId());
			$select->where(AdminLockPeer::ROW_ID, $row->getId());
			
			$lock = AdminLockPeer::getInstance()->fetchRow($select);
			$lock->delete();
		}
		
		Service_Base::redirectToTable($this->_getParam('fromtable'));
		
		$front = Zend_Controller_Front::getInstance();
		$router = $front->getRouter();
		$url = $router->assemble(array('action' => 'list', 'id' => null));
		header("Location: $url");
		exit($url);
	}
			
	/**
	 * Set status to cancel, return product count and exit.
	 * 
	 * @param OrdersRow $row
	 * @return void
	 */
	protected function _cancel($row)
	{
		if ($row->isPlaced() || $row->isUncall() || $row->isWaitPaidCard()) {
			$row->setStatus(OrdersService::STATUS_ORDER_CANCELED);
			$row->save();
			$discount = CouponService::getInstance()->restoreCupon($row);
			if (count($discount) > 0) CouponService::getInstance()->setFCCodeStatus($discount['code_id'] , 1);
			$this->_returnProductCount($row);
			OrdersService::getInstance()->notifyOrderCanceled($row);
			$this->_exit($row);
		}
		
		$configMail = Config::getInstance()->mail;
		if ($configMail->enabled) {
			$subj = "Отмена заказа {$row->getId()}";
			if ($row->isTransferedToDelivery()) {
				$suffix = $row->getOrderOperatorRowByOperatorId()->getName();
				$suffix = ' в логистической компании ' . $suffix;
				$subj .= $suffix;
			}
			
			$message = $subj . $configMail->sign;
			$mail = new Zend_Mail('UTF-8');
			$mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
			$mail->setSubject($subj);
			$mail->setBodyHtml($message);
			$mail->addTo('order@detmir.ru');
			$mail->send();
		}
				$fc_peer = ForeignCouponCodePeer::getInstance();
				$select = $fc_peer->select()->setIntegrityCheck(false);
				$select->join('foreign_coupon_code2order' ,'foreign_coupon_code.id = foreign_coupon_code2order.code_id' , array('code_id' , 'order_id') );
				$select->where('order_id = ?' , $row->getId());
				$discount = $fc_peer->fetchRow($select);
				if (count($discount) > 0) CouponService::getInstance()->setFCCodeStatus ($discount['code_id'] , 1);
		$row->setStatus('wait_for_cancel');
		$row->save();
			
		$this->_returnProductCount($row);
		$this->_exit($row);
	}
	
	/**
	 * Return product count, use when order was cancelled.
	 * 
	 * @param OrdersRow $row
	 * @return void
	 */
	protected function _returnProductCount($row)
	{
		/* @var $row OrdersRow */
		$rowset = $row->getOrder2productRowsetByOrderId();
		foreach ($rowset as $o2p) {
			$count = (int) $o2p->getCount();
			/* @var $product ProductRow */
			$product = $o2p->getProductRowByProductId();
			//если заказ был отменен до обновления остатков из домино.
			$acceptedAt = $row->getAcceptedAt();
			$acceptedAtEmpty = false;
			if (empty($acceptedAt) || $acceptedAt == '0000-00-00 00:00:00') {
				$acceptedAtEmpty = true;
			}
			$restsAtTime = strtotime($product->getRestsAt());
			if ($restsAtTime < strtotime($row->getCreatedAt())) {
			//@todo расскоментировать когда реализуем повтороное списание остатков если заапрувили на следующий день
			//if ($acceptedAtEmpty && $restsAtTime < strtotime($row->getCreatedAt()) || $restsAtTime < strtotime($row->getAcceptedAt())) {
				// Обновляем остатки одним запросом, чтобы избежать изменения остатков другим процессом
				$product->setCount(new Zend_Db_Expr("product.count + $count"));
				// Если остатки > 0, ставим флаг "есть в наличии"
				$product->setIsPresent(new Zend_Db_Expr("IF((product.count + $count) > 0, 1, 0)"));
				$product->save();
			}
		}
	}
	
	/**
	 * Set status to uncall and exit.
	 * 
	 * @param OrdersRow $row
	 * @return void
	 */
	protected function _uncall($row)
	{
		$status = OrdersService::getInstance()->getOrderStatusByKey('uncall');
		$row->setOrderStatusId($status->getId());
		$row->save();
		$this->_exit($row);
	}
	
}